import { useQuery, useQueryClient } from '@tanstack/react-query'

import { getAuthToken } from '../utils/auth'
import { logger as defaultLogger } from '../utils/logger'

import type { Logger } from '@codebuff/common/types/contracts/logger'

// Query keys for type-safe cache management
export const usageQueryKeys = {
  all: ['usage'] as const,
  current: () => [...usageQueryKeys.all, 'current'] as const,
}

interface UsageResponse {
  type: 'usage-response'
  usage: number
  remainingBalance: number | null
  balanceBreakdown?: {
    free: number
    paid: number
  }
  next_quota_reset: string | null
  autoTopupEnabled?: boolean
}

interface FetchUsageParams {
  authToken: string
  logger?: Logger
}

/**
 * Fetches usage data from the API
 */
export async function fetchUsageData({
  authToken,
  logger = defaultLogger,
}: FetchUsageParams): Promise<UsageResponse> {
  const appUrl = process.env.NEXT_PUBLIC_CODEBUFF_APP_URL
  if (!appUrl) {
    throw new Error('NEXT_PUBLIC_CODEBUFF_APP_URL is not set')
  }

  const response = await fetch(`${appUrl}/api/v1/usage`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      fingerprintId: 'cli-usage',
      authToken,
    }),
  })

  if (!response.ok) {
    logger.error(
      { status: response.status },
      'Failed to fetch usage data from API',
    )
    throw new Error(`Failed to fetch usage: ${response.status}`)
  }

  const data = (await response.json()) as UsageResponse
  return data
}

export interface UseUsageQueryDeps {
  logger?: Logger
  enabled?: boolean
  refetchInterval?: number | false
  refetchIntervalInBackground?: boolean
}

/**
 * Hook to fetch usage data from the API
 * Returns TanStack Query result directly - no store synchronization needed
 */
export function useUsageQuery(deps: UseUsageQueryDeps = {}) {
  const { 
    logger = defaultLogger, 
    enabled = true, 
    refetchInterval = false,
    refetchIntervalInBackground = false,
  } = deps
  const authToken = getAuthToken()

  return useQuery({
    queryKey: usageQueryKeys.current(),
    queryFn: () => fetchUsageData({ authToken: authToken!, logger }),
    enabled: enabled && !!authToken,
    staleTime: 0, // Always consider data stale for immediate refetching
    gcTime: 5 * 60 * 1000, // 5 minutes
    retry: false, // Don't retry failed usage queries
    refetchOnMount: 'always', // Always refetch on mount to get fresh data when banner opens
    refetchOnWindowFocus: false, // CLI doesn't have window focus
    refetchOnReconnect: false, // Don't auto-refetch on reconnect
    refetchInterval, // Poll at specified interval (when banner is visible)
    refetchIntervalInBackground, // Required for terminal environments without browser visibility API
  })
}

/**
 * Hook to manually trigger a usage data refresh
 */
export function useRefreshUsage() {
  const queryClient = useQueryClient()

  return () => {
    queryClient.invalidateQueries({ queryKey: usageQueryKeys.current() })
  }
}
